package com.xyun.task.job;

import io.xyun.mpapi.api.WechatAPI;
import io.xyun.mpapi.api.WechatAPIImpl;
import io.xyun.mpapi.util.HttpTool;
import io.xyun.mpapi.vo.MPAccount;
import io.xyun.mpapi.vo.api.FollowList;
import io.xyun.mpapi.vo.api.Follower;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.xyun.base.utils.ConfigUtils;
import com.xyun.base.utils.DataRow;
import com.xyun.base.utils.SpringContextHolder;
import com.xyun.task.bean.WeixinCustomer;
import com.xyun.task.service.TaskService;

/**
 * 微信相关的 定时拉取任务
 * @author: 	xyun
 * @version: 	1.0 
 * @Copyright:  Copyright (c) 2016 
 * @createtime: 2016年1月18日 下午3:41:57
 */
@Service
@Lazy(false)
public class WechatJob
{
	private TaskService service = SpringContextHolder.getBean(TaskService.class);
	private Log log = Logs.get();
	
	//全量拉取用户信息，一天一次就OK
	public void updateAll(){
		updateUserInfo(1);
	}
	//增量拉取用户信息，频率可以快点
	public void updateNew(){
		updateUserInfo(0);
	}
	public void updateRemark(){
		updateUserInfo(3);
	}
    public void updateUserInfo(int type){
		try {
			SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
	    	java.util.Date date_start=new java.util.Date();  
	    	String str_start=sdf.format(date_start);
	    	log.info("---------定时任务开始-----------"+str_start);
	        String appid="";
	        String appsecret = "";
	        String access_token ="";
	        String acc_type ="";
	        //获取要同步的公众号
	        List list = service.getMpaccList();
	        if(null!=list && list.size()>0){
	        	log.info("需要同步的公众号有："+list.toString());
	        	for(Object obj:list){
	        		DataRow dr = new DataRow((HashMap)obj);
	        		String weixinpk = dr.getString("weixinpk");
	        		appid = dr.getString("appid");
	        	    appsecret = dr.getString("appsecret");
	        	    acc_type = dr.getString("account_type");
	        	    if(!acc_type.equals("1")){
	        	    	//订阅号 不支持
	        	    	log.info("acc_type="+acc_type);
	        	    	continue ;
	        	    }
	        	    // 获取access_token 
	        	    //log.info("---------获取accessToken-----------");
	        	    access_token = getAccessToken(weixinpk,appid,appsecret);
	        	    // 初始化接口
	        	    MPAccount _mc = new MPAccount();
	        	    _mc.setMpId(weixinpk);
	                _mc.setAppId(appid);
	                _mc.setAppSecret(appsecret);
	                WechatAPI api = WechatAPIImpl.create(_mc);
	                //log.info("---------获取用户列表 更新用户信息开始-----------");
	                if(type==1){
	                	doUpdateAllUser(api,access_token,weixinpk,null);
	                }else if(type==0){
	                	doUpdateNewUser(api,access_token,weixinpk,null);
	                }else if(type==3){
	                	doUpdateRemark(api,access_token,weixinpk);
	                }
	        	}
	        }
	        java.util.Date date_end=new java.util.Date();  
	    	String str_end=sdf.format(date_end);
	        log.info("---------定时任务结束-----------"+str_end);
		} catch (Exception e) {
			e.printStackTrace();
		}
    	
    }
    
    public String getAccessToken(String weixinpk,String appid,String appsecret){
    	 String token_url = ConfigUtils.get("weixin.accessTokenUrl");
         token_url = String.format(token_url,weixinpk,appid,appsecret);
         String accessToken = HttpTool.get(token_url);
         return accessToken;
    }
    /**
     * 全部用户更新，更新频率不要太高，一天一次就够了
     * @author：	 xyun
     * @createtime： 2016年4月5日 下午5:47:03
     * @param api
     * @param access_token
     * @param weixinpk
     * @param nextopenid
     */
    public void doUpdateAllUser(WechatAPI api,String access_token,String weixinpk,String nextopenid){
    	FollowList followlist = api.getFollowerList(nextopenid,access_token);
    	if(followlist!=null){
        	List openid_list =followlist.getOpenIds();
        	for(Object obj_openid:openid_list){
        		String openid = (String)obj_openid;
        		//log.info("---------获取用户信息-----------");
        		Follower follower =api.getFollower(openid, null, access_token);
        		WeixinCustomer weixin = service.getWxCustomer(weixinpk,openid);
        		String type ="0";
        		int state = follower.getSubscribe()==1?0:1;
        		if(weixin!=null){
        			//更新
        			//log.info("更新数据！");
        			weixin.setHeadimgurl(follower.getHeadimgurl());
        			weixin.setNickname(follower.getNickname());
        			weixin.setSex(follower.getSex());
        			weixin.setState(state);
        			weixin.setCity(follower.getCity());
        			weixin.setJoinDate(new Date(follower.getSubscribeTime()*1000));
        			weixin.setUnionid(follower.getUnionid());
        		}else{
        			//插入
        			//log.info("插入新数据！");
        			type="1";
        			weixin = new WeixinCustomer();
        			String id =UUID.randomUUID().toString().replaceAll("-", "");
        			weixin.setId(id);
        			weixin.setWeixinPk(weixinpk);
        			weixin.setOpenid(follower.getOpenid());
        			weixin.setJoinDate(new Date(follower.getSubscribeTime()));
        			weixin.setHeadimgurl(follower.getHeadimgurl());
        			weixin.setNickname(follower.getNickname());
        			weixin.setSex(follower.getSex());
        			weixin.setState(state);
        			weixin.setCity(follower.getCity());
        			weixin.setUnionid(follower.getUnionid());
        		}
        		//log.info("---------更新用户信息-----------"+weixin.toString());
        		service.saveWxCustomer(weixin, type);
        		
        	}
        }
    	if(followlist.getNextOpenId()!=null && followlist.getNextOpenId().equals("") && followlist.getCount()<10000){
    		doUpdateAllUser(api,access_token,weixinpk,followlist.getNextOpenId());
    	}
    }
    
    public void doUpdateNewUser(WechatAPI api,String access_token,String weixinpk,String nextopenid){
    	WeixinCustomer weixinCustomer = new WeixinCustomer();
    	weixinCustomer.setWeixinPk(weixinpk);
    	weixinCustomer.setHeadimgurl("isnotnull");
    	List<WeixinCustomer> list = service.getWxCustomerList(weixinCustomer);
    	int i=0;
    	for(Object obj:list){
    		WeixinCustomer entity = (WeixinCustomer)obj;
    		Follower follower = api.getFollower(entity.getOpenid(), null, access_token);
    		int state = follower.getSubscribe()==1?0:1;
    		entity.setHeadimgurl(follower.getHeadimgurl());
    		entity.setNickname(follower.getNickname());
    		entity.setSex(follower.getSex());
    		entity.setJoinDate(new Date(follower.getSubscribeTime()));
    		entity.setState(state);
    		entity.setCity(follower.getCity());
    		entity.setUnionid(follower.getUnionid());
    		service.saveWxCustomer(entity, "0");
    		i++;
    		log.info(weixinpk+"增量拉取"+follower.getOpenid()+"用户信息"+i+"个");
    	}
    	log.info(weixinpk+"共增量拉取用户信息"+i+"个");
    }
    
    /**
     * 微信绑定数每日统计
     * @author：	 xyun
     * @createtime： 2016年5月26日 下午5:31:52
     */
    public void bindReport(){
    	service.bindReport();
    }
    /**
     * 根据客户姓名，设置ta的备注名
     * @author：	 xyun
     * @createtime： 2016年5月26日 下午5:32:59
     */
    public void doUpdateRemark(WechatAPI api,String access_token,String weixinpk){
    	WeixinCustomer weixinCustomer = new WeixinCustomer();
    	weixinCustomer.setWeixinPk(weixinpk);
    	weixinCustomer.setState(0);
    	weixinCustomer.setCustname("isnotnull");
    	List<WeixinCustomer> list = service.getWxCustomerList(weixinCustomer);
    	if(list!=null && list.size()>0){
    		for(Object obj:list){
    			try {
    				WeixinCustomer entity = (WeixinCustomer)obj;
        			String custname= entity.getCustname();
            		boolean result = api.updateRemark(entity.getOpenid(), custname);
            		log.info("设置"+entity.getOpenid()+"备注名为"+custname+result);
				} catch (Exception e) {
					// TODO: handle exception
				}
    			
    		}
    	}
    }
}
